﻿namespace AB.ServiceDirectory.Dao
{
    using System.Data.SqlClient;
    using System.Linq;
    using System.Transactions;
    using Commons.DataFilters;
    using Entities;

    /// <summary>
    /// ASupportingMaterialDao Class
    /// </summary>
    public class ASupportingMaterialDao
    {

        /// <summary>
        /// Data Context
        /// </summary>
        private static readonly ServicesDirectoryDataContext DataContext = DB.Context;

        /// <summary>
        /// Finds all data.
        /// </summary>
        /// <returns>SupportingMaterial list query</returns>
        public static IQueryable<SupportingMaterial> FindAllData()
        {
            IQueryable<SupportingMaterial> query = (from s in DataContext.SupportingMaterials select s).Distinct();
            return query;
        }

        /// <summary>
        /// Gets the list organization count.
        /// </summary>
        /// <param name="filter">The filter.</param>
        /// <returns>Number of organization list</returns>
        public static int GetListOrganizationCount(ASupportingMaterialFilter filter)
        {
            IQueryable<SupportingMaterial> query = from o in DataContext.SupportingMaterials select o;
            return GetListFilter(query, filter).Count();
        }

        /// <summary>
        /// Gets the supporting material by id.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <returns>SupportingMaterial object</returns>
        public static SupportingMaterial GetSupportingMaterialById(int id)
        {
            SupportingMaterial supportingMaterial =
                DataContext.SupportingMaterials.FirstOrDefault(s => s.SupportingMaterialId == id);
            return supportingMaterial;
        }

        /// <summary>
        /// Gets the list supporting material.
        /// </summary>
        /// <param name="filter">The filter.</param>
        /// <param name="softType">Type of the soft.</param>
        /// <param name="startRowIndex">Start index of the row.</param>
        /// <param name="maxRows">The max rows.</param>
        /// <returns>SupportingMaterial list query</returns>
        public static IQueryable<SupportingMaterial> GetListSupportingMaterial(ASupportingMaterialFilter filter,
                                                                               string softType, int startRowIndex,
                                                                               int maxRows)
        {
            IQueryable<SupportingMaterial> query = from c in DataContext.SupportingMaterials select c;

            //1. Filter Method
            if (filter != null)
            {
                query = GetListFilter(query, filter);
            }
            //2. Sorting Column
            query = GetListSort(query, softType);

            //3. Paging
            query = query.Skip(startRowIndex).Take(maxRows);
            return query;
        }

        /// <summary>
        /// Gets the list sort.
        /// </summary>
        /// <param name="query">The query.</param>
        /// <param name="softType">Type of the soft.</param>
        /// <returns>SupportingMaterial list query</returns>
        private static IQueryable<SupportingMaterial> GetListSort(IQueryable<SupportingMaterial> query, string softType)
        {
            bool desc = false;
            if (!string.IsNullOrEmpty(softType))
            {
                string[] value = softType.Split(' ');
                softType = value[0];
                if (value.Length > 1)
                {
                    desc = (value[1] == "DESC");
                }
                switch (softType)
                {
                    case "URL":
                        query = desc
                                    ? query.OrderByDescending(o => o.Url)
                                    : query.OrderBy(o => o.Url);
                        break;

                    case "Description":
                        query = desc
                                    ? query.OrderByDescending(o => o.Description)
                                    : query.OrderBy(o => o.Description);
                        break;

                    case "Type":
                        query = desc
                                    ? query.OrderByDescending(o => o.Type)
                                    : query.OrderBy(o => o.Type);
                        break;

                    case "AddedBy":
                        query = desc
                                    ? query.OrderByDescending(o => o.User.Account)
                                    : query.OrderBy(o => o.User.Account);
                        break;

                    case "AddedDate":
                        query = desc
                                    ? query.OrderByDescending(o => o.AddedDate)
                                    : query.OrderBy(o => o.AddedDate);
                        break;

                    case "IsActive":
                        query = desc
                                    ? query.OrderByDescending(o => o.IsActive)
                                    : query.OrderBy(o => o.IsActive);
                        break;

                    default:
                        query = desc
                                    ? query.OrderByDescending(o => o.SupportingMaterialId)
                                    : query.OrderBy(o => o.SupportingMaterialId);
                        break;
                }
            }
            return query;
        }

        /// <summary>
        /// Inserts the supporting material.
        /// </summary>
        /// <param name="supportingMaterial">The supporting material.</param>
        /// <returns></returns>
        public bool InsertSupportingMaterial(SupportingMaterial supportingMaterial)
        {
            bool flag;
            try
            {
                using (var transaction = new TransactionScope())
                {
                    if (string.IsNullOrEmpty(supportingMaterial.Url))
                    {
                        return false;
                    }
                    DataContext.SupportingMaterials.InsertOnSubmit(supportingMaterial);
                    DataContext.SubmitChanges();

                    transaction.Complete();
                    flag = true;
                }
            }
            catch (SqlException ex)
            {
                Log.GetLog(this).Error(ex);
                flag = false;
            }
            return flag;
        }

        /// <summary>
        /// Updates the status.
        /// </summary>
        /// <param name="supportingMaterialId">The supporting material id.</param>
        /// <param name="active">if set to <c>true</c> [active].</param>
        /// <returns></returns>
        public static bool UpdateStatus(int supportingMaterialId, bool active)
        {
            bool flag = false;
            SupportingMaterial query =
                DataContext.SupportingMaterials.FirstOrDefault(c => c.SupportingMaterialId == supportingMaterialId);
            if (query != null)
            {
                query.IsActive = active;
                DataContext.SubmitChanges();
                flag = true;
            }

            return flag;
        }

        /// <summary>
        /// Updates the supporting material.
        /// </summary>
        /// <param name="supportingMaterial">The supporting material.</param>
        /// <returns></returns>
        public bool UpdateSupportingMaterial(SupportingMaterial supportingMaterial)
        {
            bool flag = false;

            try
            {
                using (var transaction = new TransactionScope())
                {
                    SupportingMaterial material = DataContext.SupportingMaterials.FirstOrDefault(
                        s => s.SupportingMaterialId == supportingMaterial.SupportingMaterialId);
                    if (material != null)
                    {
                        material.Url = supportingMaterial.Url;
                        material.Description = supportingMaterial.Description;
                        material.Type = supportingMaterial.Type;
                        DataContext.SubmitChanges();
                        transaction.Complete();

                        flag = true;
                    }
                }
            }
            catch (SqlException ex)
            {
                Log.GetLog(this).Error(ex);
                flag = false;
            }
            return flag;
        }

        /// <summary>
        /// Gets the list filter.
        /// </summary>
        /// <param name="query">The query.</param>
        /// <param name="filter">The filter.</param>
        /// <returns></returns>
        private static IQueryable<SupportingMaterial> GetListFilter(IQueryable<SupportingMaterial> query,
                                                                    ASupportingMaterialFilter filter)
        {
            if (!filter.IsActive)
            {
                query = query.Where(c => c.IsActive);
            }

            return query;
        }

        /// <summary>
        /// Sets the supporting material status.
        /// </summary>
        /// <param name="supportingMaterialId">The supporting material id.</param>
        /// <param name="status">if set to <c>true</c> [status].</param>
        public void SetSupportingMaterialStatus(int supportingMaterialId, bool status)
        {
            var supportingMaterial =
                DataContext.SupportingMaterials.FirstOrDefault(s => s.SupportingMaterialId == supportingMaterialId);
            if (supportingMaterial != null)
            {
                supportingMaterial.IsActive = status;
                DataContext.SubmitChanges();
            }
        }
    }
}